package com.mk.eventbus;

import android.os.Looper;

import java.lang.reflect.InvocationTargetException;
import java.lang.reflect.Method;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.Iterator;

/**
 * Created by mk on 2017/9/13.
 */

public class EventBus {
    private static final EventBus eventBus = new EventBus();
    /**
     * 某种对象事件 key---value 订阅者的对象
     */
    private HashMap<Class<?>, ArrayList<Subscription>> subscripMaps = new HashMap<>();
    private String methodName="imChatEvent";
    private AsyThreadHandler asyThreadHandler=new AsyThreadHandler(this);
    private MainUiThreadHandler mainUiThreadHandler=new MainUiThreadHandler(Looper.getMainLooper());
    /**
     * 主线程
     */
    protected static final int MainThread=1;
    /**
     * 子线程
     */
    protected static final int AsyThread=0;
    public static  EventBus getInstance() {
        return eventBus;
    }

    /**
     * 这块通过反射做分析
     *
     * @param subscriber
     */
    public void regist(Object subscriber) {
        Class<?> clazz = subscriber.getClass();
        Method[] methods = clazz.getMethods();
        for (Method m : methods) {
            String name = m.getName();
            if(name.startsWith(methodName)){//以这个名字开头
                Class<?>[] parameterTypes = m.getParameterTypes();//获取参数类型
                /**
                 * key下对应的订阅者集合
                 */
                ArrayList<Subscription> subscriptions;
                if(subscripMaps.containsKey(parameterTypes[0])){
                    subscriptions = subscripMaps.get(parameterTypes[0]);
                }else {//不包含
                    subscriptions=new ArrayList<>();
                }
                int length = name.substring(methodName.length()).length();
                Subscription sub=length==0?
                        new Subscription(subscriber,new SubscroptionMethod(m,AsyThread)):
                        new Subscription(subscriber,new SubscroptionMethod(m,MainThread));
                subscriptions.add(sub);
                //存到map
                subscripMaps.put(parameterTypes[0],subscriptions);
            }
        }
    }

    /**
     * 解除绑定
     * @param subscriber
     */
    public void unregist(Object subscriber) {
        Class<?> clazz = subscriber.getClass();
        Method[] methods = clazz.getMethods();
        for (Method m:methods) {
            String name = m.getName();
            if(name.startsWith(methodName)){//取到注册的方法
                Class<?>[] parameterTypes = m.getParameterTypes();
                ArrayList<Subscription> subscriptions = subscripMaps.get(parameterTypes[0]);
                Iterator<Subscription> iterator = subscriptions.iterator();
                while (iterator.hasNext()){
                    Subscription next = iterator.next();
                    if(next.subscroptioner==subscriber){//取订阅者相同的
                        iterator.remove();
                    }
                }
            }
        }
        //使逻辑更加完成

    }

    public void post(Object event) {
        Class<?> clazz = event.getClass();
        ArrayList<Subscription> subscriptions = subscripMaps.get(clazz);
        for (Subscription s:subscriptions) {//循环发送事件消息
            if (s.subscroptionMethod.threadType==AsyThread){
                asyThreadHandler.post(s,event);
            }else {
                mainUiThreadHandler.post(s,event);
            }
        }
    }

    /**
     * 通过反射调用执行方法
     */
    public void invoke(final Subscription subscription,final Object event,Method m){
        try {
            m.invoke(subscription.subscroptioner,event);
        } catch (IllegalAccessException e) {
            e.printStackTrace();
        } catch (InvocationTargetException e) {
            e.printStackTrace();
        }

    }
}
